package com.jerry.consumer.controller;

import com.jerry.common.bean.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

/**
 * 一旦调用服务方法失败并抛出了错误信息后，会自动调用
 * @HystrixCommand标注好的fallbackMethod调用类中的指定方法
 */
@RestController
@RequestMapping("/shop/user")
public class UserController {

	@Value("${provider.userUrl}")
	private String userUrl;

	@Autowired
	private DiscoveryClient discoveryClient;
	@Autowired
	private RestTemplate restTemplate;

	//查询用户列表
	@SuppressWarnings("unchecked")
	@GetMapping("/list")
	@HystrixCommand(fallbackMethod="hystrix_list")
	public List<User> getUserList() {
		List<User> userList = restTemplate.getForObject(this.userUrl+"/user/list",List.class);
		return userList;
	}

	//根据id查询用户
	@GetMapping("/get/{id}")
	@HystrixCommand(
			fallbackMethod="hystrix_get",
			commandProperties = {
					@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000"),
					@HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value="10000")
			},
			threadPoolProperties = {
					@HystrixProperty(name="coreSize",value="1"),
					@HystrixProperty(name="maxQueueSize",value="10")
			}
	)
	public User getUser(@PathVariable("id") Long id) {
		return restTemplate.getForObject(this.userUrl + "/user/get/" + id, User.class);
	}

	//增加一个用户
	@GetMapping("/add")
	@HystrixCommand(fallbackMethod="hystrix_add")
	public boolean addUser(User user) {
		return restTemplate.postForObject(this.userUrl + "/user/add", user, Boolean.class);
	}

	//更新一个用户
	@GetMapping("/update")
	@HystrixCommand(fallbackMethod="hystrix_update")
	public boolean updateUser(User user) {
		return restTemplate.postForObject(this.userUrl + "/user/update", user, Boolean.class);
	}

	//删除一个用户
	@GetMapping("/delete/{id}")
	@HystrixCommand(fallbackMethod="hystrix_delete")
//	@HystrixCommand(
//			fallbackMethod="hystrix_delete",
//			commandProperties = {
//					@HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")
//			}
//	)
	public void deleteUser(@PathVariable("id") Long id) {
		restTemplate.delete(this.userUrl + "/user/delete/"+id);
	}

	//查询provider-user的实例信息
	@GetMapping("/userInstance")
	public List<ServiceInstance> userInstance() {
		return this.discoveryClient.getInstances("provider-user");
	}


	/////////////////////////// 熔断处理 开始////////////////////////////////////
	public List<User> hystrix_list() {
		List<User> userList = new ArrayList<User>();
		User user = new User();
		user.setId(-1l);
		user.setName("数据库存中没有数据--@HystrixCommand");
		user.setAge(-1);
		user.setBalance(0.0f);
		userList.add(user);
		return  userList;
	}

	// 需要获得回退的原因，只需在fallback方法上添加珍上Throwable参数即可
	public User hystrix_get(@PathVariable("id") Long id, Throwable throwable) {
		System.out.println("进入回退方法，异常==="+throwable);

		User user = new User();
		user.setId(-1l);
		user.setName("数据库存中没有数据--@HystrixCommand");
		user.setAge(-1);
		user.setBalance(0.0f);
		return  user;
	}

	public boolean hystrix_add(User user) {
		System.out.println("新增方法发生异常");
		return false;
	}

	public boolean hystrix_update(User user) {
		System.out.println("更新方法发生异常");
		return false;
	}

	public void hystrix_delete(@PathVariable("id") Long id) {
		System.out.println("删除方法发生异常");
	}
	/////////////////////////// 熔断处理 结束////////////////////////////////////


}
